package com.kingyun.gpsinspection.purificationservice.services.activitiservice.base;

import com.alibaba.fastjson.JSONObject;
import com.cqhilink.api.common.utils.enums.RespCodeEnum;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kingyun.gpsinspection.purificationservice.common.activiti.ActivitiConstants;
import com.kingyun.gpsinspection.purificationservice.common.bean.Page;
import com.kingyun.gpsinspection.purificationservice.common.enums.WorkFlowStateEnum;
import com.kingyun.gpsinspection.purificationservice.facade.service.activiti.base.WorkFlowService;
import com.kingyun.gpsinspection.purificationservice.services.activitiservice.ext.Meditor.MeditorFactory;
import com.kingyun.gpsinspection.purificationservice.services.activitiservice.ext.util.ActivitiMakeDataUtil;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.shiro.util.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 流程相关serviceImpl
 * @author zjh
 * @since 20170525
 */

@Service
public  class BaseWorkFlowServiceImpl implements WorkFlowService {


    private Logger _log = LoggerFactory.getLogger(BaseWorkFlowServiceImpl.class);

    @Autowired
    protected TaskService taskservice;

    @Autowired
    protected HistoryService historyService;

    @Autowired
    protected RuntimeService runtimeService;

    @Autowired
    protected ManagementService managementService;

    @Autowired
    protected IdentityService identityService;




    /**
     * 得到某个用户的待办任务(分页)
     *
     * @param userId
     * @param page
     * @return
     */
    @Override
    public Page getTodoTasksByPage(String userId, Page page) {
        _log.debug("查询用户:{}待办任务开始",userId);
        TaskQuery taskQuery = taskservice.createTaskQuery().taskCandidateOrAssigned(userId).active().orderByTaskCreateTime().desc();



        //=====================条件过滤开始==============================
       /* if(page.getParams()!=null){
            Object taskName= page.getParams().get("taskName");
            if(taskName!=null){
                //任务名称
                taskQuery.taskNameLike(taskName.toString());
            }

        }*/
        Object categoryName= page.getSearch();
        if(categoryName!=null){
            //流程类型名称
            taskQuery.processDefinitionNameLike("%"+categoryName.toString()+"%");
        }
        Map<String, Object> params = page.getParams();
        if(params!=null){
            //流程定义key
            Object processDefinitionKey= params.get("processDefinitionKey");
            if(processDefinitionKey!=null){
                taskQuery.processDefinitionKey(processDefinitionKey.toString());
            }
        }

        //=====================条件过滤结束================================

        //用户签收或者是没签收的任务
        List<Task> assigneeTasks = taskQuery.listPage(page.getOffset(), page.getLimit());

        //多人任务，组任务自行领取任务
       /* for(Task task:assigneeTasks){
            if(Strings.isNullOrEmpty(task.getAssignee())){
                taskservice.claim(task.getId(),userId);
            }
        }*/

        Long count = taskQuery.count();
        List<JSONObject> taskDatas = ActivitiMakeDataUtil.makeTodoTaskPageData(assigneeTasks);
       // makeBusinessData(taskDatas);
        page.setRows(taskDatas);
        page.setTotal(count);
        _log.debug("查询用户:{}待办任务结束",userId);
        return page;
    }

    /**
     * 封装业务数据
     *
     * @param list
     */
    private void makeBusinessData(List<JSONObject> list){
        try{
            for(JSONObject taskObj:list){
                Object result=null;
                String businessKey=taskObj.get("businessKey").toString();
                if(ActivitiConstants.BusinessType.daily.getType().equals(taskObj.get("taskType"))){
                    //日常操作
                    result = MeditorFactory.getInstance().createDailyThings(businessKey);
                }else if(ActivitiConstants.BusinessType.problem.getType().equals(taskObj.get("taskType"))){
                    //问题处理
                    result = MeditorFactory.getInstance().createProblem(businessKey);
                }else if(ActivitiConstants.BusinessType.tour.getType().equals(taskObj.get("taskType"))){
                    //巡回
                    result = MeditorFactory.getInstance().createPatrolInspection(businessKey);
                }else if(ActivitiConstants.BusinessType.maintain.getType().equals(taskObj.get("taskType"))){
                    //维保
                    result = MeditorFactory.getInstance().createMaintenance(businessKey);
                }
                taskObj.put("businessObj",result);
            }
        }catch (Exception e){
            throw  new RuntimeException("获取业务数据异常");
        }

    }





    /**
     * 得到某个用户的已办任务
     *
     * @param userId
     * @param page
     * @return
     */
    @Override
    public Page getDoneTaskByPage(String userId, Page page) {
        _log.debug("查询用户:{}已办任务开始",userId);
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery().
                taskAssignee(userId).taskCompletedBefore(new Date()).orderByHistoricTaskInstanceEndTime().desc();
        Map<String, Object> params = page.getParams();
        if(params!=null){
            Object processDefinitionKey= params.get("processDefinitionKey");
            if(processDefinitionKey!=null){
                historicTaskInstanceQuery.processDefinitionKey(processDefinitionKey.toString());
            }
        }
        List<HistoricTaskInstance> doneTasks = historicTaskInstanceQuery.listPage(page.getOffset(), page.getLimit());
        long count = historicTaskInstanceQuery.count();
        page.setRows(ActivitiMakeDataUtil.makeDoneTaskPageData(doneTasks));
        page.setTotal(count);
        _log.debug("查询用户:{}已办任务结束",userId);
        return  page;
    }

    /**
     * 得到某个用户的发起的流程(包含已经完成和未完成的)
     *
     * @param userId 用户id
     * @param page 分页参数
     * @return
     */
    @Override
    public Page getRunningProcessinstances(String userId, Page page) {
        _log.debug("查询用户{}:发起的流程开始",userId);
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().startedBy(userId);
        Map<String, Object> params = page.getParams();
        if(params!=null){
            Object processDefinitionKey= params.get("processDefinitionKey");
            if(processDefinitionKey!=null){
                historicProcessInstanceQuery.processDefinitionKey(processDefinitionKey.toString());
            }
        }
        List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.orderByProcessInstanceStartTime().desc().listPage(page.getOffset(), page.getLimit());
        long count = historicProcessInstanceQuery.count();
        page.setRows(ActivitiMakeDataUtil.makeHistoricProcessInstancePageData(historicProcessInstances));
        page.setTotal(count);
        _log.debug("查询用户{}:发起的流程结束",userId);
        return  page;
    }

    /**
     * 得到某个流程实例的任务列表(包括完成和未完成的)
     *
     * @param processInstanceId 流程实例id
     * @param type              1.完成,2 未完成
     * @return
     */
    @Override
    public Map<String, Object> getHistoricTaskInstance(String processInstanceId, String type) {
        _log.debug("查询流程实例:{}任务列表开始",processInstanceId);
        Map<String,Object> result=Maps.newHashMap();
        List<HistoricTaskInstance> hisTaskList=Lists.newArrayList();
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId);
        if(Strings.isNullOrEmpty(type)){
            //所有的列表
            hisTaskList = historicTaskInstanceQuery.list();
        }else{
            if(WorkFlowStateEnum.FINISH.getCode().equals(type)){
                //完成的任务列表
                hisTaskList=historicTaskInstanceQuery.finished().list();
            }else{
                //未完成的任务
                hisTaskList=historicTaskInstanceQuery.unfinished().list();
            }
        }
        result.put("rows", ActivitiMakeDataUtil.makeDoneTaskPageData(hisTaskList));
        result.put("total",hisTaskList.size());
        _log.debug("查询流程实例:{}任务列表结束",processInstanceId);
        return null;
    }

    /**
     * 根据流程Key启动流程
     *
     * @param key    流程key
     * @param businessId 业务ID
     * @param params 流程相关变量
     * @param userId 用户id
     * @return
     */
    @Override
    public Map<String, Object> startProcessInstanceByKey(String key,String businessId, Map<String, Object> params,String userId) {
        _log.debug("启动流程key值:{}开始",key);
        identityService.setAuthenticatedUserId(userId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,businessId, params);
        Map<String, Object> result = makeProcessInstanceStartResult(processInstance);
        _log.debug("启动流程:{}结束",key);
        return result;
    }

    /**
     * 根据流程Id启动流程
     *
     * @param id 流程Id
     * @param businessId 业务ID
     * @param params 流程变量
     * @param userId 用户id
     * @return
     */
    @Override
    public Map<String, Object> startProcessInstanceById(String id,String businessId, Map<String, Object> params,String userId) {
        _log.debug("启动流程Id值:{}开始",id);
        identityService.setAuthenticatedUserId(userId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(id,businessId, params);
        Map<String, Object> result = makeProcessInstanceStartResult(processInstance);
        _log.debug("启动流程Id值结束",id);
        return result ;
    }

    /**
     * 得到某个参与的流程
     *
     * @param userId 参与人Id
     * @param page   分页参数
     * @return
     */
    @Override
    public Page getPartakeByPage(String userId, Page page,String type) {
        _log.debug("查询用户ID:{}参与的流程开始",userId);
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().involvedUser(userId);
        List<HistoricProcessInstance> historicProcessInstances = Lists.newArrayList();
        //查询所有我参与的流程
        if(Strings.isNullOrEmpty(type)){
            historicProcessInstances = historicProcessInstanceQuery.listPage(page.getOffset(), page.getLimit());
        }else{
            if(WorkFlowStateEnum.FINISH.getCode().equals(type.trim())){
                historicProcessInstances = historicProcessInstanceQuery.finished().listPage(page.getOffset(),page.getLimit());
            }else{
                historicProcessInstances = historicProcessInstanceQuery.unfinished().listPage(page.getOffset(),page.getLimit());
            }
        }
        _log.debug("查询用户ID:{}参与的流程结束",userId);
       return page;
    }

    /**
     * 完成任务(非委托任务)
     *
     * @param taskId 任务Id
     * @param commet 注释
     * @param userId 用户id
     * @return
     */
    @Override
    public  Map<String, Object> completeTask(String taskId,Map<String,Object> variable, String commet,String userId) {
        _log.debug("完成任务ID:{}开始",taskId);
        Map<String,Object> result = Maps.newHashMap();
        //带批注
        if(!Strings.isNullOrEmpty(commet)){
            taskservice.addComment(taskId,null,commet);
        }

        List<Task> list = taskservice.createTaskQuery().taskId(taskId).taskCandidateOrAssigned(userId).list();
        if(CollectionUtils.isEmpty(list)){
            _log.info("此用户{}没有{}任务",userId,taskId);
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
            result.put("msg","用户没有该任务");
        }else{
            for(Task task:list){
                if(Strings.isNullOrEmpty(task.getAssignee())){
                    taskservice.claim(taskId,userId);
                }
            }
            taskservice.complete(taskId,variable);
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg","任务完成");
        }

        _log.debug("完成任务ID:{}结束",taskId);
        return result;
    }

    /**
     * 完成代理任务
     *
     * @param taskId   任务Id
     * @param variable 流程变量
     * @param commet   注释
     * @param userId   用户id
     * @return
     */
    @Override
    public Map<String, Object> completeDelegateTask(String taskId, Map<String, Object> variable, String commet, String userId) {
        _log.debug("完成任务ID:{}开始",taskId);
        Map<String,Object> result = Maps.newHashMap();
        //带批注
        if(!Strings.isNullOrEmpty(commet)){
            taskservice.addComment(taskId,null,commet);
        }

        List<Task> list = taskservice.createTaskQuery().taskId(taskId).list();
        if(CollectionUtils.isEmpty(list)){
            _log.info("此用户{}没有{}任务",userId,taskId);
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
            result.put("msg","用户没有该任务");
        }else{
            for(Task task:list){
                if(Strings.isNullOrEmpty(task.getAssignee())){
                    taskservice.claim(taskId,userId);
                }
            }
            taskservice.resolveTask(taskId);
            taskservice.complete(taskId,variable);
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg","任务完成");
        }

        _log.debug("完成任务ID:{}结束",taskId);
        return result;
    }

    /**
     * 驳回任务
     *
     * @param taskId
     * @param variable
     * @param commet
     * @return
     */
    @Override
    public Map<String, Object> reject(String taskId, Map<String, Object> variable, String commet) {
        _log.debug("任务{}驳回开始",taskId);
        Map<String,Object> result = Maps.newHashMap();
        try{
            List<Task> list = taskservice.createTaskQuery().taskId(taskId).active().list();
            Task task = list.get(0);
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            String startUserId = historicProcessInstance.getStartUserId();
            variable.put(ActivitiConstants.MANUAL_PERSON, Arrays.asList(startUserId));
            taskservice.complete(taskId,variable);
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg","任务驳回成功");
        }catch (Exception e){
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
            result.put("msg","任务驳回失败");
            throw new RuntimeException("任务驳回出错");
        }
        _log.debug("任务{}驳回结束",taskId);
        return result;
    }

    /**
     * 代理任务
     *
     * @param taskId         任务Id
     * @param delegateUserId 代理用户Id
     * @return
     */
    @Override
    public Map<String, Object> delegateTask(String taskId, String delegateUserId) {
        _log.debug("设置代理任务{}给{}开始",taskId,delegateUserId);
        Map<String,Object> result = Maps.newHashMap();
        taskservice.delegateTask(taskId,delegateUserId);
        result.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
        result.put("msg","任务完成");;
        _log.debug("设置代理任务{}给{}结束",taskId,delegateUserId);
        return result;
    }

    /**
     * 终止流程
     *
     * @param taskId 任务id
     * @param reason
     * @return
     */
    @Override
    public Map<String, Object> stopProcessInstance(String taskId,String reason) {
        _log.debug("终止任务{}开始",taskId);
        Map<String,Object> result = Maps.newHashMap();
        List<Task> list = taskservice.createTaskQuery().taskId(taskId).active().list();
        if(list!=null||list.size()==0){
            throw new RuntimeException("没有相关的任务");
        }
        Task task=list.get(0);
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(),reason);
        result.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
        result.put("msg","终止任务成功");;
        _log.debug("终止任务{}结束",taskId);
        return result;
    }


    /**
     * 封装流程启动成功后返回的数据
     * @param processInstance 流程实例
     * @return
     */
    private Map<String,Object> makeProcessInstanceStartResult(ProcessInstance processInstance){
        Map<String,Object> result = Maps.newHashMap();
        if(processInstance !=null){
            String processInstanceId = processInstance.getProcessInstanceId();
            _log.info("流程实例ID{}",processInstanceId);
            result.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg","启动流程成功");
        }else{
            result.put("state", RespCodeEnum.RESP_CODE_ENUM_false.code());
            result.put("msg","启动流程失败");
        }
        return result;
    }




}
